<?php
	function D($model)
	{
		$class = 'lib_'.$model;
		$file = APP_DIR.'/protected/model/'.$class.'.php';
		if(file_exists($file)) {
			// include($file);
			if(class_exists($class)){
				return new $class();
			}
		}else{
			$lib_base = new lib_base();
			$lib_base->table_name = 'qc_'.$model;
			$lib_base->pk = 'id';
			return $lib_base;
		}
	}


	function dump_log0($data){
		if(is_array($data)){
			$jsonArray = json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
		}elseif(is_object($data)){
			$data = object_to_array($data);
			$jsonArray = json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
			// $jsonArray = "\r\n".$data;
		}else{
			// $jsonArray = json_encode($data,true);
			$jsonArray = $data;
		}
		$jsonArray .= "\r\n".date('Y-m-d H:i:s')."\r\n";
		// $jsonArray .= arg('c')."/".arg('a')."\r\n";

		$backtrace = debug_backtrace();
		foreach ($backtrace as $call) {
			// 检查是否为对象的方法调用
			if (isset($call['class'])) {
				// 返回类名和方法名
				$jsonArray .= $call['class'] . '::' . $call['function'] . "\n";
			}
			// 打印出调用栈的每个函数的名称
			// $jsonArray .= $call['function'] . "//";
		}

		file_put_contents(APP_DIR.'/2.txt', $jsonArray);
	}

	function dump_log1($data,$status=1){
		if(is_array($data)){
			$jsonArray = json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
		}elseif(is_object($data)){
			$data = object_to_array($data);
			$jsonArray = json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
			// $jsonArray = "\r\n".$data;
		}else{
			$jsonArray = json_encode($data,true);
			// $jsonArray = "\r\n".$data;
		}
		$jsonArray .= "\r\n".date('Y-m-d H:i:s')."\r\n";
		if($status==0){
			file_put_contents(APP_DIR.'/1.txt', $jsonArray);
		}else{
			file_put_contents(APP_DIR.'/1.txt', $jsonArray, FILE_APPEND);
		}

	}



	/*加密解密 ENCODE 加密   DECODE 解密*/
	function pp_encrypt($string, $operation = 'ENCODE', $key = '', $expiry = 0)
	{
		if($operation == 'DECODE') {
			$string =  str_replace('_', '/', $string);
		}
		$key_length = 4;
		$key = md5($key != '' ? $key : 'NDQC');
		$fixedkey = md5($key);
		$egiskeys = md5(substr($fixedkey, 16, 16));
		$runtokey = $key_length ? ($operation == 'ENCODE' ? substr(md5(microtime(true)), -$key_length) : substr($string, 0, $key_length)) : '';
		$keys = md5(substr($runtokey, 0, 16) . substr($fixedkey, 0, 16) . substr($runtokey, 16) . substr($fixedkey, 16));
		$string = $operation == 'ENCODE' ? sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$egiskeys), 0, 16) . $string : base64_decode(substr($string, $key_length));

		$i = 0; $result = '';
		$string_length = strlen($string);
		for ($i = 0; $i < $string_length; $i++){
			$result .= chr(ord($string[$i]) ^ ord($keys[$i % 32]));
		}
		if($operation == 'ENCODE') {
			$retstrs =  str_replace('=', '', base64_encode($result));
			$retstrs =  str_replace('/', '_', $retstrs);
			return $runtokey.$retstrs;
		} else {
			if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$egiskeys), 0, 16)) {
				return substr($result, 26);
			} else {
				return '';
			}
		}
	}








	function hide_err($msg, $traces)
	{
	    dump($msg);
	    // dump($traces);
	    exit;
	}

	function I($class)
	{
		$file = APP_DIR.'/protected/include/'.$class.'.php';
		if(file_exists($file)) {
			include($file);
			// return new $class();
	    }
	}
	function get_cookie($name)
	{
		if(empty($name)){return false;}
		if(isset($_COOKIE[$name])){
			return $_COOKIE[$name];
		}else{
			return false;
		}
	}
	function set_cookie($name,$value,$time=0,$path='/',$domain='')
	{
		if(empty($name)){return false;}
		$_COOKIE[$name]=$value;				//及时生效
		$s = $_SERVER['SERVER_PORT'] == '443' ? 1 : 0;
		if(!$time){
			return setcookie($name,$value,0,$path,$domain,$s);
		}else{
			return setcookie($name,$value,$time,$path,$domain,$s);
		}
	}
	function array_to_object($arr)
	{
	    if (gettype($arr) != 'array') {
	        return;
	    }
	    foreach ($arr as $k => $v) {
	        if (gettype($v) == 'array' || getType($v) == 'object') {
	            $arr[$k] = (object)array_to_object($v);
	        }
	    }

	    return (object)$arr;
	}
	function object_to_array($obj)
	{
	    $obj = (array)$obj;
	    foreach ($obj as $k => $v) {
	        if (gettype($v) == 'resource') {
	            return;
	        }
	        if (gettype($v) == 'object' || gettype($v) == 'array') {
	            $obj[$k] = (array)object_to_array($v);
	        }
	    }

	    return $obj;
	}
	function get_host()
	{
		$host = $_SERVER['HTTP_HOST'];
		$arr = explode('.', $host);
		$domain[0] = $arr[0];
		$domain[1] = $arr[1].'.'.$arr[2].'.'.$arr[3];
		return $domain;
	}
	function get_ip($type = 0,$adv=false)
	{
	    $type       =  $type ? 1 : 0;
	    static $ip  =   NULL;
	    if ($ip !== NULL) return $ip[$type];
	    if($adv){
	        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
	            $arr    =   explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
	            $pos    =   array_search('unknown',$arr);
	            if(false !== $pos) unset($arr[$pos]);
	            $ip     =   trim($arr[0]);
	        }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
	            $ip     =   $_SERVER['HTTP_CLIENT_IP'];
	        }elseif (isset($_SERVER['REMOTE_ADDR'])) {
	            $ip     =   $_SERVER['REMOTE_ADDR'];
	        }
	    }elseif (isset($_SERVER['REMOTE_ADDR'])) {
	        $ip     =   $_SERVER['REMOTE_ADDR'];
	    }
	    // IP地址合法验证
	    $long = sprintf("%u",ip2long($ip));
	    $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
	    return $ip[$type];
	}
	function joinStr($arr,$add=',')
	{
	    // @sort($arr);
	    $str='';
	    if($arr){
	        foreach($arr as $val){
	            $str.=($str?$add:'').$val;
	        }
	    }
	    return $str;
	}
	function qcing_hash($password)
	{
	    return md5(md5($password) . 'qcing_salt_SmTRx');
	}

	function arrBase($array,$arrAdd=[])
    {
        foreach ($array as $value) {
            $data[$value] = arg($value);
        }
        if($arrAdd){
        	//数组
        	if(is_array($arrAdd)){
            	$data = array_merge($arrAdd,$data);
            }else{

            	switch($arrAdd){
					case 'add_time':
						$arrAdd = array(
				            'add_time' => date('Y-m-d H:i:s'),
				        );
						break;
					case 'up_time':
						$arrAdd = array(
				            'up_time' => date('Y-m-d H:i:s'),
				        );
						break;
					case 'password':
						$arrAdd = array(
				            'password' => qcing_hash(arg('password')),
				        );
						break;
					case 'pass_time':
						$arrAdd = array(
							'password' => qcing_hash(arg('password')),
				            'add_time' => date('Y-m-d H:i:s'),
				        );
						break;
				}
            }
            $data = array_merge($arrAdd,$data);
        }
        return $data;
    }

	function en_yqmcode($user_id)
	{
	    static $source_string = 'E5FCDG3HQA4B1NOPIJ2RSTUV67MWX89KLYZ';
	    $num = $user_id;
	    $code = '';
	    while ( $num > 0) {
	        $mod = $num % 35;
	        $num = ($num - $mod) / 35;
	        $code = $source_string[$mod].$code;
	    }
	    if(empty($code[3]))
	        $code = str_pad($code,4,'0',STR_PAD_LEFT);
	    return $code;
	}
	function de_yqmcode($code)
	{
	    static $source_string = 'E5FCDG3HQA4B1NOPIJ2RSTUV67MWX89KLYZ';
	    if (strrpos($code, '0') !== false)
	        $code = substr($code, strrpos($code, '0')+1);
	    $len = strlen($code);
	    $code = strrev($code);
	    $num = 0;
	    for ($i=0; $i < $len; $i++) {
	        $num += strpos($source_string, $code[$i]) * pow(35, $i);
	    }
	    return $num;
	}
	function make_orderno()
	{
		$str = date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
		return $str;
	}
	// function isAjax()
	// {
	// 	if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'){
	// 	  return true;
	// 	}else{
	// 	  return false;
	// 	}
	// }

	/*移动端判断*/
	function isMobile()
	{
	    // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
	    if (isset ($_SERVER['HTTP_X_WAP_PROFILE']))
	    {
	        return true;
	    }
	    // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
	    if (isset ($_SERVER['HTTP_VIA']))
	    {
	        // 找不到为flase,否则为true
	        return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
	    }
	    // 脑残法，判断手机发送的客户端标志,兼容性有待提高
	    if (isset ($_SERVER['HTTP_USER_AGENT']))
	    {
	        $clientkeywords = array ('nokia',
	            'sony',
	            'ericsson',
	            'mot',
	            'samsung',
	            'htc',
	            'sgh',
	            'lg',
	            'sharp',
	            'sie-',
	            'philips',
	            'panasonic',
	            'alcatel',
	            'lenovo',
	            'iphone',
	            'ipod',
	            'blackberry',
	            'meizu',
	            'android',
	            'netfront',
	            'symbian',
	            'ucweb',
	            'windowsce',
	            'palm',
	            'operamini',
	            'operamobi',
	            'openwave',
	            'nexusone',
	            'cldc',
	            'midp',
	            'wap',
	            'mobile'
	            );
	        // 从HTTP_USER_AGENT中查找手机浏览器的关键字
	        if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT'])))
	        {
	            return true;
	        }
	    }
	    // 协议法，因为有可能不准确，放到最后判断
	    if (isset ($_SERVER['HTTP_ACCEPT']))
	    {
	        // 如果只支持wml并且不支持html那一定是移动设备
	        // 如果支持wml和html但是wml在html之前则是移动设备
	        if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html'))))
	        {
	            return true;
	        }
	    }
	    return false;
	}
	//是否微信访问
	function isWx()
	{
	    return strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger');
	}
	// 是否手机号码
	function isTel($string)
	{
	    if(preg_match('/^[1]+[3,4,5,7,8,9]+\d{9}$/', $string)){
				return true;
		}else{
			return false;
		}
	}
	//自定义函数手机号隐藏中间四位
	function hide_phone($str)
	{
		$str=$str;
		$resstr=substr_replace($str,'****',3,4);
		return $resstr;
	}




    function htmlPrefix($deep)
    {
        // 根据角色深度处理名称前缀
        $prefix = '';
        if ($deep > 1) {
            for ($i = 1; $i <= $deep - 1; $i++) {
                $prefix .= '&nbsp;&nbsp;&nbsp;├ ';
            }
            $prefix .= '&nbsp;';
        }
        return $prefix;
    }

	function formatTreeData(&$data, $parent_id = 0, $deep = 1)
    {
		$tempTreeArr = [];
        foreach ($data as $key => $val) {
            if ($val['parent_id'] == $parent_id) {
                // 记录深度
                $val['deep'] = $deep;
				$val['adds'] = htmlPrefix($deep);
                // 根据角色深度处理名称前缀
                $val['name_h1'] = htmlPrefix($deep) . $val['name'];
				$tempTreeArr[] = $val;
                $tempTreeArr = array_merge($tempTreeArr,formatTreeData($data, $val['id'], $deep + 1));
            }
		}
		// dump($tempTreeArr);
        return $tempTreeArr;
	}
	//树形菜单data
	function formatChildData($data, $parent_id = 0)
    {
        $tree = [];
		$newData = [];
		$data = formatTreeData($data);
        //循环重新排列
        foreach ($data as $v) {
            $newData[$v['id']] = $v;
        }

        foreach ($newData as $key => $val) {
            if ($val['parent_id'] > $parent_id) {
                //不是根节点的将自己的地址放到父级的child节点
                $newData[$val['parent_id']]['children'][] = &$newData[$key];
            } else {
                //根节点直接把地址放到新数组中
                $tree[$val['id']] = &$newData[$val['id']];
            }
        }
        return $tree;
    }

	//树形菜单data
	function get_child_data($data, $pk = 'id', $pid = 'parent_id', $child = 'children', $root = 0)
    {
        $tree = [];
		$newData = [];
		$data = get_child_list($data);
        //循环重新排列
        foreach ($data as $datum) {
            $newData[$datum[$pk]] = $datum;
        }
        foreach ($newData as $key => $datum) {
            if ($datum[$pid] > $root) {
                //不是根节点的将自己的地址放到父级的child节点
                $newData[$datum[$pid]][$child][] = &$newData[$key];
            } else {
                //根节点直接把地址放到新数组中
                $tree[] = &$newData[$datum[$pk]];
            }
        }
        return $tree;
	}
	//树形菜单
	function get_child_list(&$data, $parent_id = 0, $deep = 1)
    {
		$tempTreeArr = [];
        foreach ($data as $key => $val) {
            if ($val['parent_id'] == $parent_id) {
                // 记录深度
                $val['deep'] = $deep;
                // 根据角色深度处理名称前缀
                $val['name_h1'] = htmlPrefix($deep) . $val['name'];
				$tempTreeArr[] = $val;
                $tempTreeArr = array_merge($tempTreeArr,get_child_list($data, $val['id'], $deep + 1));
            }
		}
		// dump($tempTreeArr);
        return $tempTreeArr;
    }
	//授权
	function getTreeForAuth($array, $ids)
    {
    	$accessIds = explode(',',$ids);
    	$tree = get_child_data($array);
    	$authTree = getTreeForAuthArr($tree,$accessIds);
        return $authTree;
    }
    function getTreeForAuthArr($array, $accessIds)
    {
        foreach ($array as $key => $val) {
            $val['auth'] = in_array($val['id'], $accessIds);

            if($val['children']){
            	$val['children'] = getTreeForAuthArr($val['children'], $accessIds);
            }
            $tree[] = $val;
        }
        return $tree;
    }


	function list_to_tree($list, $pk='id', $pid = 'parent_id', $child = 'children', $root = 0)
	{
		// 创建Tree
		$tree = array();
		if(is_array($list)) {
			// 创建基于主键的数组引用
			$refer = array();
			foreach ($list as $key => $data) {
				$list[$key][$pid] = $data[$pid];
				$list[$key]['value'] = $data['id'];
				$list[$key]['text'] = $data['name'];
				$refer[$data[$pk]] =& $list[$key];
			}
			foreach ($list as $key => $data) {
				// 判断是否存在parent
				$parentId =  $data[$pid];
				if ($root == $parentId) {
					$tree[] =& $list[$key];
				}else{
					if (isset($refer[$parentId])) {
						$parent =& $refer[$parentId];
						$parent[$child][] =& $list[$key];
					}
				}
			}
		}
		return $tree;
	}




	function tableOrder($name,$k)
	{
		$pageurl=$_SERVER["QUERY_STRING"];
		$cur=(strpos($_GET['list_order'],'desc'))?'_asc':'_desc';
		$cur2=(strpos($_GET['list_order'],'desc'))?'↓':'↑';
		$tabtit='<a href="'.url_set_value($pageurl,'list_order',$k.$cur).'"'.$cur.'>'.$name.$cur2.'</a>';
		return $tabtit;
	}

	function tabTit($nav)
	{
		$tabtit = '';
		$pageurl=$_SERVER["QUERY_STRING"];
		//$nav=array('全部问答','未回复问答');
		foreach($nav as $k=>$v){
			$cur=($_GET['tab']==$k)?' class="cur"':'';
			$tabtit.='<a href="'.url_set_value($pageurl,'tab',$k).'"'.$cur.'>'.$v.'</a>';
		}
		return $tabtit;
	}

	//替换url参数
	function url_set_value($url,$key,$value)
	{
		parse_str($url,$arr);
		$arr[$key]=$value;
		return '?'.http_build_query($arr);
	}

	//分页
	function showPage($array,$tag='',$ps='page')
	{
	    // $this->page_num=$pagearr['total_page'];
	    // $pcur_start=$this->pabs($this->page_num,$this->page_cur,$this->single_num);
	    // $this->start=$pcur_start['start'];

	    $ps='page';
	    $p=$array['current_page']; //当前页
	    $allNum=$array['total_count']; //总数
	    $allPage=$array['total_page']; //总页数
	    // $tag && $tag='&'.$this->pfit($tag);
	    // '.url_set_value($pageurl,$ps,$pagearr['next_page']).'
	    $pageurl=$_SERVER["QUERY_STRING"];

	    $pStr='<table border="0" cellspacing="0" cellpadding="0"><tr><td>';
	    $pStr.='<span>共'.$allNum.'条 第'.$p.'/'.$allPage.'页</span>';
	    $i=$p-1;
	    if($allPage<6||$p<6){
	        for($i=1;$i<=$allPage&&$i<=6;$i++) {
	            $pStr.=($i==$p)?'<i>'.$i.'</i>':'<a href="'.url_set_value($pageurl,$ps,$i).'">'.$i.'</a>';
	        }
	        if($allPage>6){
	            $pStr.=($p<$allPage)?'<span>...</span><a href="'.url_set_value($pageurl,$ps,$allPage).'">'.$allPage.'</a>':'';
	        }
	    }
	    else {
	        $pStr.='<a href="'.url_set_value($pageurl,$ps,1).'">1</a><span>...</span>';
	        for($i=2;$i>0;$i--){$pStr.='<a href="'.url_set_value($pageurl,$ps,$p-$i).'">'.(int)($p-$i).'</a>';}
	        $pStr.='<i>'.$p.'</i>';
	        $ii=$p;$ii++;
	        for($i=1;$ii<=$allPage;$i++,$ii++) {if($i>2)break;$pStr.='<a href="'.url_set_value($pageurl,$ps,$ii).'">'.$ii.'</a>';}
	        if($allPage==$ii) {$pStr.='<a href="'.url_set_value($pageurl,$ps,$allPage).'">'.$allPage.'</a>';}
	        else if($allPage-$p>2){$pStr.='<span>...</span><a href="'.url_set_value($pageurl,$ps,$allPage).'">'.$allPage.'</a>';}
	    }
	    $pStr.='</td></tr></table>';
	    return $pStr;
	}

	//html_radios
	function html_select($name, $array, $checked, $val_name='')
	{
		$html = '<select class="select" name="'.$name.'">';
	    $html .= '<option value="0">===无===</option>';

	    if(is_array($array)){
	        $html .= html_options($array, $checked, $val_name);
	    }
		$html .= '</select>';
		return $html;
	}


	//html_options
	function html_options($array, $checked, $val_name='')
	{

	    if(is_array($array)){
	        $html = '';
	        foreach($array as $key => $val){
	        	if(!$val_name){
	        		$v['id'] = $key;
	        		$v['name'] = $val;
	        	}else{
	        		$val['name'] = $val[$val_name];
	        	}

	        	$html .= '<option value="'.$val['id'].'"';
	        	if ($val['id'] == $checked) {
	                $html .= ' selected="selected"';
	            }
	            $html .= ' />';
	            // if($val['level']){
	            // 	$html .= str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;',$val['level']).'└─';
	            // }
	            if($val['adds']){
	            	$html .= $val['adds'];
	            }
	            $html .= $val['name'] . '</option>';
	            if ($val['children']) {
	            	$html .= html_options($val['children'], $checked, $val_name);
	            }
	            unset($children);
	        }
	        $html .= '';
	    }

		return $html;
	}

	//html_radios
	function html_radios($name, $options, $checked)
	{
		$_output = '';
		foreach($options as $key => $value){
			$_output .= ' <input type="radio" name="'.$name.'" value="'.$key. '"';
		    if ((string)$key == $checked) {
		        $_output .= ' checked="checked"';
		    }
		    $_output .= ' /> '.$value;
		}
		return $_output;
	}

	//html_checkboxes
	function html_checkboxes($name,$options,$checked){

	    $_output = '';
		foreach($options as $key => $value){

			$_output .= ' <input type="checkbox" name="'.$name.'[]" value="'.$key. '"';
		    if (is_array($checked)) {
		        if (in_array($key,$checked)) {
		            $_output .= ' checked="checked"';
		        }
		    } elseif ($key == $checked) {
		        $_output .= ' checked="checked"';
		    }
		    $_output .= ' /> '.$value;
		}
		return $_output;
	}


	function time_tran($the_time) {
		$now_time = date("Y-m-d H:i:s", time());

		$now_time2 = time();
		$show_time = strtotime($the_time);
		$dur = $now_time2 - $show_time;

		if ($dur < 0) {
			return $the_time;
		} else {
			if ($dur < 60) {
				return $dur . '秒前';
			} else {
				if ($dur < 3600) {
					return floor($dur / 60) . '分钟前';
				} else {
					if ($dur < 86400) {
						return floor($dur / 3600) . '小时前';
					} else {
						if ($dur < 259200) {//3天内
							return floor($dur / 86400) . '天内';
						} else {
							return $the_time;
						}
					}
				}
			}
		}
	}

	function checkPrivilege($url){
		return true;
	}


	/**
	 * 数据导出到excel(csv文件)
	 * @param $fileName
	 * @param array $tileArray
	 * @param array $dataArray
	 */
	function export_excel($fileName, $tileArray = [], $dataArray = [])
	{
		ini_set('memory_limit', '512M');
		ini_set('max_execution_time', 0);
		ob_end_clean();
		ob_start();
		header("Content-Type: text/csv");
		header("Content-Disposition:filename=" . $fileName);
		$fp = fopen('php://output', 'w');
		fwrite($fp, chr(0xEF) . chr(0xBB) . chr(0xBF));// 转码 防止乱码(比如微信昵称)
		fputcsv($fp, $tileArray);
		$index = 0;
		foreach ($dataArray as $item) {
			if ($index == 1000) {
				$index = 0;
				ob_flush();
				flush();
			}
			$index++;
			fputcsv($fp, $item);
		}
		ob_flush();
		flush();
		ob_end_clean();
	}


	// 过滤掉emoji表情
	function filterEmoji($str)
	{
		$str = preg_replace_callback( '/./u',
		function (array $match) {
			return strlen($match[0]) >= 4 ? '' : $match[0];
		},
		$str);
		return $str;
	}
